package com.qipa.netty.service.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.qipa.entity.ChatKeywords;
import com.qipa.entity.Game;
import com.qipa.entity.RequestLog;
import com.qipa.entity.ResponseLog;
import com.qipa.common.ResultModel;
import com.qipa.model.ChatOpModel;
import com.qipa.model.GameModel;
import com.qipa.netty.handler.TextWebSocketFrameHandler;
import com.qipa.netty.heartbeat.WebSocketChannelMap;
import com.qipa.netty.service.HandlerService;
import com.qipa.service.*;
import com.qipa.utils.*;
import com.qipa.vo.ChatListVo;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by MySelf on 2018/11/21.
 */
@Component
public class HandlerServiceImpl extends HandlerService {

    Logger logger = Logger.getLogger(HandlerServiceImpl.class);

    @Autowired
    RedisUtils redisUtils;
    @Autowired
    IGameService gameService;
    @Autowired
    IChatKeywordsService chatKeywordsService;
    @Autowired
    TextWebSocketFrameHandler textWebSocketFrameHandler;
    @Autowired
    IResponseLogService responseLogService;
    @Autowired
    IRequestLogService requestLogService;
    @Autowired
    IChatOpService chatOpService;

    @Override
    public ResultModel pushChat(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest) {

        String queryString = fullHttpRequest.getUri();
//        logger.info("请求链接：" + queryString);
//        logger.info(com.qipa.netty.util.HttpUtil.getGetParamsFromChannel(fullHttpRequest));

        Map<String, String> getParamsFromChannel = com.qipa.netty.util.HttpUtil.getGetParamsFromChannel(fullHttpRequest);
        String userId = getParamsFromChannel.get("userId");
        String roleId = getParamsFromChannel.get("roleId");
        String roleName = getParamsFromChannel.get("roleName");
        String gameId = getParamsFromChannel.get("gameId");
        String serviceId = getParamsFromChannel.get("serviceId");
        String chatContents = getParamsFromChannel.get("chatContents");
        String random = getParamsFromChannel.get("random");
        String sign = getParamsFromChannel.get("sign");
        /*if (StringUtils.isBlank(userId) || StringUtils.isBlank(roleId) || StringUtils.isBlank(roleName) || gameId == null || StringUtils.isBlank(roleId)
                || StringUtils.isBlank(serviceId) || StringUtils.isBlank(chatContents)
                || StringUtils.isBlank(random) || StringUtils.isBlank(sign)) {
            return ResultModel.fail("参数错误");
        }*/

        List<GameModel> listJoinGameCompanyJoinShared = gameService.getListJoinGameCompanyJoinShared(new GameModel());

        Game game1 = gameService.selectById(gameId);
        if (game1 == null) {
            return ResultModel.fail("游戏不存在");
        }

        String gamePayKey = game1.getGamePayKey();

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(userId);
        stringBuffer.append(roleId);
//        logger.info("角色名===="+roleName);
        stringBuffer.append(URLEncoder.encode(roleName).toLowerCase());
        stringBuffer.append(gameId);
        stringBuffer.append(serviceId);
        stringBuffer.append(URLEncoder.encode(chatContents).toLowerCase());
        stringBuffer.append(random);
        stringBuffer.append(gamePayKey);
        String string = stringBuffer.toString();
        String s = MD5Password32.GetMD5Code(string);
        if (!s.equalsIgnoreCase(sign)) {
            //保存日志
            ResponseLog responseLog = new ResponseLog();
            responseLog.setLogType(1);
            responseLog.setOrderId(roleId);
            responseLog.setGameId(Integer.valueOf(gameId));
            responseLog.setRequestUrl(queryString);
            responseLog.setRequestMd5String("拼接串：" + string);
            responseLog.setRequestTime(new Date());
            responseLog.setReturnContent("签名错误");
            responseLogService.insert(responseLog);

            logger.info("拼接串：" + string);
            logger.info("签名：" + s);
            return ResultModel.fail("签名错误");
        }
        Date currdate = new Date();
        ChatListVo chatListVo = new ChatListVo();
        chatListVo.setAddTime(currdate);
        //chatListService.insert(chatListModel);

        //存入redis set
        UUID uuid = UUID.randomUUID();
        String uuidStr = uuid.toString();
        uuidStr = uuidStr.replace("-", "");
        chatListVo.setId(uuidStr);
        chatListVo.setUserId(userId);
        chatListVo.setRoleId(roleId);
        chatListVo.setRoleName(roleName);
        chatListVo.setGameId(Integer.valueOf(gameId));
        chatListVo.setServiceId(serviceId);
        chatListVo.setChatContents(chatContents);

        byte[] serialize = ObjectUtils.serialize(chatListVo);
        long timeMillis = System.currentTimeMillis();
        redisUtils.add("chatZSet_" + gameId, serialize, timeMillis);
        redisUtils.add("chatZSet", serialize, timeMillis);

        //违规的聊天记录
        Date date1 = DateUtils.addHour(new Date(), 24);
        String chatHandleUrl = game1.getChatHandleUrl();
        EntityWrapper queryWrapper = new EntityWrapper();
//        queryWrapper.like("game_ids", gameId);
        List<ChatKeywords> simpleList = chatKeywordsService.selectList(queryWrapper);
        for (ChatKeywords chatKeywordsModel : simpleList) {
//            logger.info("遍历关键词列表");
            String keyword = chatKeywordsModel.getKeyword();
            if (StringUtils.isNotBlank(keyword)) {
                String[] split = keyword.split(";");
                for (String rule : split) {
//                    logger.info("遍历关键词：" + rule);
                    //正则表达式匹配
                    Pattern p = Pattern.compile(rule);
                    Matcher matcher = p.matcher(chatContents);//创建匹配器
                    boolean result = matcher.find();
//                    logger.info("匹配结果：" + result);
                    if (result) {
                        random = System.currentTimeMillis()+"";
                        //自动禁言24小时
                        //请求研发接口
                        StringBuffer stringBuffer2 = new StringBuffer();
                        stringBuffer2.append(userId);
                        stringBuffer2.append(roleId);
                        stringBuffer2.append(URLEncoder.encode(URLEncoder.encode(roleName)).toLowerCase());
                        stringBuffer2.append(gameId);
                        stringBuffer2.append(serviceId);
                        stringBuffer2.append(1);
                        stringBuffer2.append(date1.getTime());
                        stringBuffer2.append(URLEncoder.encode(URLEncoder.encode(chatContents)).toLowerCase());
                        stringBuffer2.append(random);
                        stringBuffer2.append(gamePayKey);
                        String string2 = stringBuffer2.toString();
                        String sign2 = MD5Password32.GetMD5Code(string2);

                        String url = "";
                        if(chatHandleUrl.contains("?")){
                            url = chatHandleUrl.trim() + "&userId=" + userId + "&roleId=" + roleId + "&roleName=" + URLEncoder.encode(roleName).toLowerCase() + "&gameId=" + gameId + "&serviceId=" + serviceId +
                                    "&opStatus=" + 1 + "&shutupTime=" + date1.getTime() + "&chatContents=" + URLEncoder.encode(chatContents) + "&random=" + random + "&sign=" + sign2;
                        }else{
                            url = chatHandleUrl.trim() + "?userId=" + userId + "&roleId=" + roleId + "&roleName=" + URLEncoder.encode(roleName).toLowerCase() + "&gameId=" + gameId + "&serviceId=" + serviceId +
                                    "&opStatus=" + 1 + "&shutupTime=" + date1.getTime() + "&chatContents=" + URLEncoder.encode(chatContents) + "&random=" + random + "&sign=" + sign2;
                        }

                        if (StringUtils.isBlank(gamePayKey) || StringUtils.isBlank(chatHandleUrl)) {
                            //保存日志
                            RequestLog requestLog = new RequestLog();
                            requestLog.setLogType(3);
                            requestLog.setOrderId(uuidStr);
                            requestLog.setGameId(Integer.valueOf(gameId));
                            requestLog.setRequestUrl(url);
                            requestLog.setRequestMd5String(string2);
                            requestLog.setRequestTime(new Date());
                            requestLog.setReturnContent("请先配置游戏参数【聊天处理接口地址和支付KEY】");
                            requestLogService.insert(requestLog);

                            //自动禁言失败，修改状态
                            chatListVo.setOpStatus(-1);
                            serialize = ObjectUtils.serialize(chatListVo);
                            redisUtils.add("chatViolationZSet", serialize, timeMillis);
                            break;
                        }

                        //保存联调日志
                        RequestLog requestLog = new RequestLog();
                        requestLog.setLogType(3);
                        requestLog.setOrderId(uuidStr);
                        requestLog.setGameId(Integer.valueOf(gameId));
                        requestLog.setRequestUrl(url);
                        requestLog.setRequestMd5String(string2);
                        requestLog.setRequestTime(new Date());
                        requestLog.setReturnContent("");
                        requestLogService.insert(requestLog);

                        /*try {*/
                        logger.info("请求地址："+url);
                            String result2 = HttpKit.get(url);
                            if (StringUtils.isBlank(result2)) {
//                                return ResultModel.fail("研发接口返回错误，请查看联调日志");
                                requestLog.setReturnContent("研发接口返回错误，请查看联调日志");
                                requestLogService.updateById(requestLog);

                                //自动禁言失败
                                chatListVo.setOpStatus(-1);
                                serialize = ObjectUtils.serialize(chatListVo);
                                redisUtils.add("chatViolationZSet", serialize, timeMillis);
                                break;
                            }

                        JSONObject jsonObject = null;
                        Boolean boo2 = true;
                        try {
                            jsonObject = JSONObject.fromObject(result2);
                        } catch (Exception e) {
                            boo2 = false;
                            e.printStackTrace();
                        }
                        //返回不是JSON，则跳出循环
                        if(!boo2) break;
                        boolean boo = jsonObject.has("code");
                            if (!boo) {
//                                return ResultModel.fail("研发接口返回错误，请查看联调日志");
                                requestLog.setReturnContent("研发接口返回错误，请查看联调日志");
                                requestLogService.updateById(requestLog);

                                //自动禁言失败
                                chatListVo.setOpStatus(-1);
                                serialize = ObjectUtils.serialize(chatListVo);
                                redisUtils.add("chatViolationZSet", serialize, timeMillis);
                                break;
                            }
                            int code = jsonObject.getInt("code");
                            String msg = jsonObject.getString("msg");
                            if (code != 200) {
//                                return ResultModel.fail("研发接口返回错误，" + msg);
                                requestLog.setReturnContent("研发接口返回错误" + msg);
                                requestLogService.updateById(requestLog);

                                //自动禁言失败
                                chatListVo.setOpStatus(-1);
                                serialize = ObjectUtils.serialize(chatListVo);
                                redisUtils.add("chatViolationZSet", serialize, timeMillis);
                                break;
                            }
                            requestLog.setReturnContent(code + "");
                            requestLogService.updateById(requestLog);
                        /*} catch (IOException e) {
                            e.printStackTrace();
//                            return ResultModel.fail("研发接口请求失败，请查看联调日志");
                            requestLog.setReturnContent("研发接口返回错误，请查看联调日志");
                            requestLogService.updateById(requestLog);

                            //自动禁言失败
                            chatListVo.setOpStatus(-1);
                            serialize = ObjectUtils.serialize(chatListVo);
                            redisUtils.add("chatViolationZSet", serialize, timeMillis);
                            break;
                        } catch (URISyntaxException e) {
                            e.printStackTrace();
//                            return ResultModel.fail("研发接口请求失败，请查看联调日志");
                            requestLog.setReturnContent("研发接口返回错误，请查看联调日志");
                            requestLogService.updateById(requestLog);

                            //自动禁言失败
                            chatListVo.setOpStatus(-1);
                            serialize = ObjectUtils.serialize(chatListVo);
                            redisUtils.add("chatViolationZSet"+gameId, serialize, timeMillis);
                            break;
                        }*/
                        //自动禁言成功
                        chatListVo.setOpStatus(1);
                        chatListVo.setOpTime(new Date());
                        chatListVo.setShutupTime(date1);
                        serialize = ObjectUtils.serialize(chatListVo);
                        redisUtils.add("chatViolationZSet", serialize, timeMillis);

                        //操作成功才有操作记录
                        ChatOpModel chatOp = new ChatOpModel();
                        chatOp.setOpStatus(1);
                        chatOp.setUserId(userId);
                        chatOp.setGameId(Integer.valueOf(gameId));
                        chatOp.setRoleId(roleId);
                        chatOp.setOpTime(new Date());
                        chatOp.setChatListId(uuidStr);
                        chatOp.setShutupTime(date1);
                        chatOpService.insert(chatOp);



//                        redisUtils.add("chatViolationZSet", serialize, timeMillis);
                        break;
                    }
                }
            }
        }
        String hhmmss = DateUtils.dateToString(currdate, DateStyle.HH_MM_SS);

        //把推送进来的聊天记录推送给所有连接
        Map<String, List<Channel>> channels = WebSocketChannelMap.getChannels();
        List<Channel> channels1 = channels.get("gameAll");//看全部游戏的弹幕连接
        if (CollectionUtils.isNotEmpty(channels1)) {
            for (Channel channel : channels1) {
                channel.writeAndFlush(new TextWebSocketFrame(game1.getGameName() + "_" + serviceId + "_" + roleName + "_" + hhmmss + "_" + chatContents));
            }
        }
        List<Channel> channels2 = channels.get(gameId);//指定游戏的连接
        if (CollectionUtils.isNotEmpty(channels2)) {
            if (channels2 != null) {
                logger.info("向指定游戏推送数据，连接数：" + channels2.size());
                for (Channel channel : channels2) {
                    channel.writeAndFlush(new TextWebSocketFrame(game1.getGameName() + "_" + serviceId + "_" + roleName + "_" + hhmmss + "_" + chatContents));
                }
            }
        }
        return ResultModel.ok();
    }

    public static void main(String[] args) {
        System.out.println(URLEncoder.encode(" *~"));
    }
}
